package auth

import (
	"cs0512/fmr/internal/pkg/middleware"
	"cs0512/fmr/internal/pkg/response"
	"strings"

	"github.com/gin-gonic/gin"
)

const authHeaderCount = 2

type AutoStrategy struct {
	basic BasicStrategy
	jwt   JWTStrategy
	ts    TokenStrategy
}

var _ middleware.AuthStrategy = &AutoStrategy{}

func NewAutoStrategy(basic BasicStrategy, jwt JWTStrategy, ts TokenStrategy) AutoStrategy {
	return AutoStrategy{
		basic: basic,
		jwt:   jwt,
		ts:    ts,
	}
}

func (a AutoStrategy) AuthFunc() gin.HandlerFunc {
	return func(c *gin.Context) {
		operator := middleware.AuthOperator{}
		authHeader := strings.SplitN(c.Request.Header.Get("Authorization"), " ", 2)

		if len(authHeader) != authHeaderCount {
			response.Fail(c, 1001, "Authorization header format is wrong.")
			c.Abort()
			return
		}

		switch authHeader[0] {
		case "Basic":
			operator.SetStrategy(a.basic)
		case "Bearer":
			operator.SetStrategy(a.jwt)
		case "cp":
			operator.SetStrategy(a.ts)
		default:
			response.Fail(c, 1001, "unrecognized Authorization header.")
			return
		}

		operator.AuthFunc()(c)

		c.Next()
	}
}
